using System;
using DanielSig;
using DanielSig.Sorcery;
using UnityEngine;

namespace DanielSig.UnityExtensions
{
	public static class XByteArrayUnity
	{
		public static void WriteQuaternion(this byte[] bytes, Quaternion value, ref uint bitIndex)
		{
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.x), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.y), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.z), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.w), 0), ref bitIndex, 32);
		}
		public static void WriteVector4(this byte[] bytes, Vector4 value, ref uint bitIndex)
		{
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.x), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.y), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.z), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.w), 0), ref bitIndex, 32);
		}
		public static void WriteVector3(this byte[] bytes, Vector3 value, ref uint bitIndex)
		{
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.x), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.y), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.z), 0), ref bitIndex, 32);
		}
		public static void WriteVector2(this byte[] bytes, Vector2 value, ref uint bitIndex)
		{
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.x), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.y), 0), ref bitIndex, 32);
		}
		public static void WriteNetworkViewID(this byte[] bytes, NetworkViewID value, ref uint bitIndex)
		{
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.GetPropertyValue<int>("a")), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.GetPropertyValue<int>("b")), 0), ref bitIndex, 32);
			bytes.Write(BitConverter.ToUInt32(BitConverter.GetBytes(value.GetPropertyValue<int>("c")), 0), ref bitIndex, 32);
		}
		
		public static Vector2 ReadVector2(this byte[] bytes, ref uint bitIndex)
		{
			uint tempX = 0;
			uint tempY = 0;
			bytes.Read(ref tempX, ref bitIndex, 32);
			bytes.Read(ref tempY, ref bitIndex, 32);
			return new Vector2(BitConverter.ToSingle(BitConverter.GetBytes(tempX), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempY), 0));
		}
		public static Vector3 ReadVector3(this byte[] bytes, ref uint bitIndex)
		{
			uint tempX = 0;
			uint tempY = 0;
			uint tempZ = 0;
			bytes.Read(ref tempX, ref bitIndex, 32);
			bytes.Read(ref tempY, ref bitIndex, 32);
			bytes.Read(ref tempZ, ref bitIndex, 32);
			return new Vector3(BitConverter.ToSingle(BitConverter.GetBytes(tempX), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempY), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempZ), 0));
		}
		public static Vector4 ReadVector4(this byte[] bytes, ref uint bitIndex)
		{
			uint tempX = 0;
			uint tempY = 0;
			uint tempZ = 0;
			uint tempW = 0;
			bytes.Read(ref tempX, ref bitIndex, 32);
			bytes.Read(ref tempY, ref bitIndex, 32);
			bytes.Read(ref tempZ, ref bitIndex, 32);
			bytes.Read(ref tempW, ref bitIndex, 32);
			return new Vector4(BitConverter.ToSingle(BitConverter.GetBytes(tempX), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempY), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempZ), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempW), 0));
		}
		public static Quaternion ReadQuaternion(this byte[] bytes, ref uint bitIndex)
		{
			uint tempX = 0;
			uint tempY = 0;
			uint tempZ = 0;
			uint tempW = 0;
			bytes.Read(ref tempX, ref bitIndex, 32);
			bytes.Read(ref tempY, ref bitIndex, 32);
			bytes.Read(ref tempZ, ref bitIndex, 32);
			bytes.Read(ref tempW, ref bitIndex, 32);
			return new Quaternion(BitConverter.ToSingle(BitConverter.GetBytes(tempX), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempY), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempZ), 0),
							   BitConverter.ToSingle(BitConverter.GetBytes(tempW), 0));
		}
		/**
			doesn't work for webplayer
			works in editor though
		*/
		public static NetworkViewID ReadNetworkViewID(this byte[] bytes, ref uint bitIndex)
		{
			NetworkViewID id = default(NetworkViewID);
			id = id.SetPropertyValue<int, NetworkViewID>("a", bytes.ReadInt(ref bitIndex, 32));
			id = id.SetPropertyValue<int, NetworkViewID>("b", bytes.ReadInt(ref bitIndex, 32));
			id = id.SetPropertyValue<int, NetworkViewID>("c", bytes.ReadInt(ref bitIndex, 32));
			return id;
		}
	}
}

